<script setup lang="ts">
import { ref, reactive, watch, onMounted, nextTick } from 'vue'
import { addDishes, getDishesList, updateDishes, deleteDishes } from '@/api/dishes'
import type { DishesSearchForm, Dishes } from '@/api/dishes/types'
import type { Page } from '@/api/common/types'
import { ElForm, ElMessage, ElMessageBox, type FormRules, type UploadProps, type UploadUserFile } from 'element-plus'
import { getIngredientListByType } from '@/api/ingredients'
import type { Ingredients } from '@/api/ingredients/types'
import { useTokenStore } from '@/stores/tokenStore'

const tokenStore = useTokenStore()

const base_url = import.meta.env.VITE_APP_BASE_API
const pageNum = ref(1)
const pageSize = ref(5)
const total = ref(0)
const dishesList = ref<Dishes[]>([])
const queryFormRef = ref()
const queryForm = reactive({
    name: ''
})
const fileList = ref<UploadUserFile[]>([])
const title = ref('新增菜品')
const dialogVisible = ref(false)
const dishesFormRef = ref()
const dishesForm = ref<Dishes>({
    name: '',
    url: '',
    description: '',
    main: '',
    mainNum: 1000,
    minor: '',
    minorNum: 200,
    seasoning: '',
    seasoningNum: 50
})
const dishFormRules = reactive<FormRules>({
    name: [{ required: true, message: '请输入菜品名称', trigger: 'blur' }],
    url: [{ required: true, message: '请上传菜品图片', trigger: 'blur' }],
    description: [{ required: true, message: '请输入菜品描述', trigger: 'blur' }],
    main: [{ required: true, message: '请选择主料', trigger: 'blur' }],
    mainNum: [{ required: true, message: '请输入主料数量', trigger: 'blur' }],
    minor: [{ required: true, message: '请选择辅料', trigger: 'blur' }],
    minorNum: [{ required: true, message: '请输入辅料数量', trigger: 'blur' }],
    seasoning: [{ required: true, message: '请选择调料', trigger: 'blur' }],
    seasoningNum: [{ required: true, message: '请输入调料数量', trigger: 'blur' }]
})



/* 查询菜品列表 */
const listDishes = async (pager = 1) => {
    pageNum.value = pager
    getDishesList(pageNum.value, pageSize.value, queryForm).then((res) => {
        dishesList.value = res.rows
        total.value = res.total
    }).catch((err) => {
        console.log(err)
    })
}

/* 新增菜品 */
const handleAdd = () => {
    title.value = '新增菜品'
    dialogVisible.value = true
    nextTick(() => {
        // 重置表单数据
        dishesForm.value = {
            name: '',
            url: '',
            description: '',
            main: '',
            mainNum: 1000,
            minor: '',
            minorNum: 200,
            seasoning: '',
            seasoningNum: 50
        }
        fileList.value = []
        // 重置表单验证状态
        dishesFormRef.value?.resetFields()
    })
}


/* 上传食材图片 */

/* 上传食材图片前 */
const handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {
    const isJPG = file.type === 'image/jpeg'
    const isPNG = file.type === 'image/png'
    const isLt1MB = file.size / 1024 / 1024 < 1
    if (!isJPG && !isPNG) {
        ElMessage.error('上传图片格式错误')
        return false
    }
    if (!isLt1MB) {
        ElMessage.error('上传图片大小不能超过 1MB')
        return false
    }
}
/* 上传食材图片成功后 */
const handleOnSuccess: UploadProps['onSuccess'] = (resp, file, files) => {
    dishesForm.value.url = resp.data
    // 上传成功后,重新校验
    dishesFormRef.value.validateField('url')
}
/* 图片删除时执行 */
const handleOnRemove: UploadProps['onRemove'] = (file, files) => {
    dishesForm.value.url = ''
    fileList.value = []
    // 删除后,重新校验
    dishesFormRef.value.validateField('url')
}
/* 图片超出个数 */
const fileLimit = ref(1)
const handleOnExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
    ElMessage.warning(`当前限制上传${fileLimit.value}张图片`)
}

/* 重置查询表单 */
const resetQueryForm = () => {
    queryFormRef.value.resetFields()
    listDishes()
}

const mainList = ref<Ingredients[]>([])
const minorList = ref<Ingredients[]>([])
const seasoningList = ref<Ingredients[]>([])

const listIngredient = async () => {
    mainList.value = await getIngredientListByType('1')
    minorList.value = await getIngredientListByType('2')
    seasoningList.value = await getIngredientListByType('3')
}

const Confirm = () => {
    dishesFormRef.value.validate(async (valid: boolean) => {
        if (valid) {
            if (!dishesForm.value.id) {
                await addDishes(dishesForm.value)
                pageNum.value = 1
            } else {
                await updateDishes(dishesForm.value)
            }
            ElMessage.success('操作成功')
            dialogVisible.value = false
            setTimeout(() => {
                listDishes(pageNum.value)
            }, 1000)
        }
    })
}

const handleEdit = (row: Dishes) => {
    title.value = '编辑菜品'
    dialogVisible.value = true
    nextTick(() => {
        dishesForm.value = { ...row }
        fileList.value = [{ name: row.name, url: base_url + row.url }]
    })
}   

const handleDelete = (id: number) => {
    ElMessageBox.confirm('确定删除该菜品吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(async () => {
        await deleteDishes(id)
        ElMessage.success('删除成功')
        setTimeout(() => {
            listDishes(pageNum.value)
        }, 1000)
    }).catch(() => {
        ElMessage.info('已取消删除')
    })
}
onMounted(() => {
    listDishes()
    listIngredient()
})
</script>

<template>
    <div>
        <!-- 查询表单 -->
        <el-form :model="queryForm" ref="queryFormRef" inline>
            <el-form-item label="菜品名称" prop="name">
                <el-input v-model="queryForm.name" placeholder="请输入菜品名称" />
            </el-form-item>
            <el-form-item>
                <el-button type="primary" icon="Search" @click="listDishes()">查询</el-button>
                <el-button type="info" icon="Refresh" @click="resetQueryForm">重置</el-button>
                <el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
            </el-form-item>
        </el-form>
        <!-- 列表数据 -->
        <el-table :data="dishesList" style="width: 100%" stripe>
            <el-table-column prop="name" label="菜品名称" align="center" />
            <el-table-column prop="url" label="菜品图片" align="center">
                <template #default="scope">
                    <el-image :src="base_url + scope.row.url" style="width: 60px; height: 60px"
                        :preview-src-list="[base_url + scope.row.url]" preview-teleported />
                </template>
            </el-table-column>
            <el-table-column prop="mainName" label="主料" align="center" />
            <el-table-column prop="minorName" label="辅料" align="center" />
            <el-table-column prop="seasoningName" label="调料" align="center" />
            <el-table-column prop="description" label="描述" align="center" />
            <el-table-column prop="createTime" label="创建时间" align="center" />
            <el-table-column label="操作" width="200px" align="center">
                <template #default="scope">
                    <el-button type="primary" icon="Edit" size="small" @click="handleEdit(scope.row)">编辑</el-button>
                    <el-button type="danger" icon="Delete" size="small" @click="handleDelete(scope.row.id)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页 -->
        <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :total="total"
            layout="total, sizes, prev, pager, next, jumper" @current-change="listDishes" @size-change="listDishes()"
            :page-sizes="[3, 5, 7, 10]" size="small" style="margin-top: 20px;" />
    </div>
    <!-- 新增菜品弹窗 -->
    <el-dialog v-model="dialogVisible" :title="title" width="700px" close-on-click-modal>
        <el-form :model="dishesForm" ref="dishesFormRef" :rules="dishFormRules" label-width="80px">
            <el-form-item label="菜品名称" prop="name">
                <el-input v-model="dishesForm.name" placeholder="请输入菜品名称" />
            </el-form-item>
            <el-form-item label="菜品图片" prop="url">
                <el-upload :action="base_url + '/dishes-service/upload/image'" list-type="picture" :headers="{Authorization: tokenStore.TOKEN}"
                    :on-success="handleOnSuccess" :before-upload="handleBeforeUpload" :on-remove="handleOnRemove"
                    :on-exceed="handleOnExceed" :file-list="fileList" :limit="fileLimit"
                    :handleBeforeUpload="handleBeforeUpload">
                    <el-button type="primary">上传菜品图片</el-button>
                </el-upload>
            </el-form-item>
            <div style="display: flex; align-items: center;">
                <el-form-item label="主料" prop="main">
                    <el-select v-model="dishesForm.main" placeholder="请选择主料" clearable style="width:180px">
                        <el-option v-for="item in mainList" :key="item.id" :label="item.name" :value="item.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="主料数量" prop="mainNum" style="width:180px">
                    <el-input type="number" v-model="dishesForm.mainNum" placeholder="请输入主料数量" />
                </el-form-item>
            </div>
            <div style="display: flex; align-items: center;">
                <el-form-item label="辅料" prop="minor">
                    <el-select v-model="dishesForm.minor" placeholder="请选择辅料" clearable style="width:180px">
                        <el-option v-for="item in minorList" :key="item.id" :label="item.name" :value="item.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="辅料数量" prop="minorNum" style="width:180px">
                    <el-input type="number" v-model="dishesForm.minorNum" placeholder="请输入辅料数量" />
                </el-form-item>
            </div>
            <div style="display: flex; align-items: center;">
                <el-form-item label="调料" prop="seasoning">
                    <el-select v-model="dishesForm.seasoning" placeholder="请选择调料" clearable style="width:180px"    >
                        <el-option v-for="item in seasoningList" :key="item.id" :label="item.name" :value="item.id" />
                    </el-select>
                </el-form-item>
                <el-form-item label="调料数量" prop="seasoningNum" style="width:180px">
                    <el-input type="number" v-model="dishesForm.seasoningNum" placeholder="请输入调料数量" />
                </el-form-item>
            </div>
            <el-form-item label="描述" prop="description">
                <el-input v-model="dishesForm.description" placeholder="请输入菜品描述" type="textarea" :rows="3" />
            </el-form-item>
        </el-form>
        <template #footer>
            <el-button @click="dialogVisible = false">取消</el-button>
            <el-button type="primary" @click="Confirm">确定</el-button>
        </template>
    </el-dialog>
</template>